#include "sync_disks_command.h"
#include "service/backend_service.h"
#include "../database/database_manager.h"
#include "command_executor.h"
#include <QDebug>
#include <QUrl>
#include <QNetworkRequest>
#include <QJsonDocument>
#include <QJsonParseError>

SyncDisksCommand::SyncDisksCommand(QObject *parent)
    : BaseCommand(parent)
    , m_commandExecutor(nullptr)
{
}

SyncDisksCommand::~SyncDisksCommand()
{
}

void SyncDisksCommand::setNetworkAccessManager(QNetworkAccessManager *networkManager)
{
    // 如果之前已经设置了 networkManager，先断开旧的连接
    if (m_networkManager) {
        disconnect(m_networkManager, &QNetworkAccessManager::finished,
                   this, &SyncDisksCommand::handleSyncDisksResponse);
    }
    
    BaseCommand::setNetworkAccessManager(networkManager);
    
    // 连接网络请求完成信号
    if (m_networkManager) {
        connect(m_networkManager, &QNetworkAccessManager::finished,
                this, &SyncDisksCommand::handleSyncDisksResponse);
    }
}

void SyncDisksCommand::setCommandExecutor(CommandExecutor *commandExecutor)
{
    m_commandExecutor = commandExecutor;
}

bool SyncDisksCommand::execute()
{
    if (!isValid()) {
        qDebug() << "SyncDisksCommand: BackendService 或 QNetworkAccessManager 未设置";
        emit syncDisksCompleted(-1, "BackendService 或 QNetworkAccessManager 未设置");
        return false;
    }
    
    qDebug() << "SyncDisksCommand: 开始同步网盘数据";
    
    // 检查是否有accessToken，如果没有则先获取
    if (!ensureAccessToken()) {
        // 如果没有选中的公司ID，无法获取accessToken
        if (!m_backendService || m_backendService->loadSelectedCompanyId().isEmpty()) {
            qDebug() << "SyncDisksCommand: 没有选中的公司ID，无法获取accessToken";
            emit syncDisksCompleted(-1, "没有选中的公司ID，无法获取accessToken");
            return false;
        }
        // 正在获取 token，返回true表示已发起获取token的请求
        return true;
    }
    
    // 获取 accessToken
    QString accessToken = CommandExecutor::getAccessToken();
    
    // 获取 baseUrl
    QString baseUrl = getBaseUrl();
    
    // 构建请求URL
    QString url = buildRequestUrl(baseUrl);
    
    qDebug() << "SyncDisksCommand: 发送同步网盘请求到:" << url;
    
    // 创建网络请求
    QNetworkRequest request = createRequest(url, "GET", "SyncDisksCommand/1.0");
    
    // 添加token到请求头
    addTokenToRequest(request, accessToken);
    
    // 发送GET请求
    QNetworkReply *reply = m_networkManager->get(request);
    qDebug() << "SyncDisksCommand: 发送同步网盘请求，reply对象:" << reply;
    
    // 设置用户数据，用于识别请求类型
    reply->setProperty("requestType", "syncDisks");
    
    return true;
}

void SyncDisksCommand::handleSyncDisksResponse(QNetworkReply *reply)
{
    // 检查对象是否仍然有效（可能在信号排队期间被销毁）
    if (!isValid()) {
        qDebug() << "SyncDisksCommand: 对象已被销毁，忽略响应";
        if (reply) {
            reply->deleteLater();
        }
        return;
    }
    
    if (!reply) {
        qDebug() << "SyncDisksCommand: 同步网盘响应为空";
        // 只有在对象仍然有效时才发送信号
        if (isValid()) {
            emit syncDisksCompleted(-1, "同步网盘响应为空");
        }
        return;
    }
    
    QString requestType = reply->property("requestType").toString();
    if (requestType != "syncDisks") {
        // 不是同步网盘请求，忽略
        reply->deleteLater();
        return;
    }
    
    // 打印reply详细信息
    qDebug() << "SyncDisksCommand: 收到同步网盘响应，reply对象:" << reply;
    qDebug() << "SyncDisksCommand: 响应状态码:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    qDebug() << "SyncDisksCommand: 响应头信息:" << reply->rawHeaderPairs();
    
    // 再次检查对象是否仍然有效
    if (!isValid()) {
        qDebug() << "SyncDisksCommand: 对象已被销毁，忽略响应";
        reply->deleteLater();
        return;
    }
    
    // 检查网络错误
    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "SyncDisksCommand: 同步网盘网络请求错误:" << reply->errorString();
        // 只有在对象仍然有效时才发送信号
        if (isValid()) {
            emit syncDisksCompleted(-1, "网络请求失败: " + reply->errorString());
        }
        reply->deleteLater();
        return;
    }
    
    // 读取响应数据
    QByteArray responseData = reply->readAll();
    qDebug() << "SyncDisksCommand: 同步网盘响应数据包:" << responseData;
    qDebug() << "SyncDisksCommand: 响应数据长度:" << responseData.size() << "字节";
    
    // 解析JSON响应
    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(responseData, &parseError);
    
    // 再次检查对象是否仍然有效
    if (!isValid()) {
        qDebug() << "SyncDisksCommand: 对象已被销毁，忽略响应";
        reply->deleteLater();
        return;
    }
    
    if (parseError.error != QJsonParseError::NoError) {
        qDebug() << "SyncDisksCommand: 同步网盘JSON解析错误:" << parseError.errorString();
        // 只有在对象仍然有效时才发送信号
        if (isValid()) {
            emit syncDisksCompleted(-2, "响应数据格式错误");
        }
        reply->deleteLater();
        return;
    }
    
    if (!doc.isObject()) {
        qDebug() << "SyncDisksCommand: 同步网盘响应数据不是有效的JSON对象";
        // 只有在对象仍然有效时才发送信号
        if (isValid()) {
            emit syncDisksCompleted(-3, "响应数据格式错误");
        }
        reply->deleteLater();
        return;
    }
    
    // 最后一次检查对象是否仍然有效
    if (!isValid()) {
        qDebug() << "SyncDisksCommand: 对象已被销毁，忽略响应解析";
        reply->deleteLater();
        return;
    }
    
    QJsonObject response = doc.object();
    parseSyncDisksResponse(response);
    
    reply->deleteLater();
}

void SyncDisksCommand::parseSyncDisksResponse(const QJsonObject &response)
{
    // 检查对象是否仍然有效
    if (!isValid()) {
        qDebug() << "SyncDisksCommand: 对象已被销毁，忽略响应解析";
        return;
    }
    
    // 解析响应字段
    int errcode = response["errcode"].toInt();
    QString errmsg = response["errmsg"].toString();
    
    qDebug() << "SyncDisksCommand: 同步网盘结果 - 错误码:" << errcode << "错误消息:" << errmsg;
    
    if (errcode == 0) {
        // 解析网盘数据
        if (response.contains("data") && response["data"].isArray()) {
            QJsonArray dataArray = response["data"].toArray();
            qDebug() << "SyncDisksCommand: 同步网盘 - 获取到网盘数量:" << dataArray.size();
            
            // 过滤掉null值并发送网盘数据信号
            QJsonArray validDisks;
            for (int i = 0; i < dataArray.size(); ++i) {
                if (!dataArray[i].isNull()) {
                    validDisks.append(dataArray[i]);
                    qDebug() << "SyncDisksCommand: 同步网盘 - 网盘数据:" << dataArray[i];
                }
            }
            
            // 再次检查对象是否仍然有效
            if (!isValid()) {
                qDebug() << "SyncDisksCommand: 对象已被销毁，无法处理网盘数据";
                return;
            }
            
            // 直接同步到数据库
            if (m_databaseManager) {
                m_databaseManager->syncDisksFromJson(validDisks);
            }
            
            // 自动同步所有网盘的根文件夹
            syncRootFolders(validDisks);
            
            // 最后一次检查对象是否仍然有效
            if (!isValid()) {
                qDebug() << "SyncDisksCommand: 对象已被销毁，无法发送完成信号";
                return;
            }
            
            // 发送同步完成信号
            emit syncDisksCompleted(0, "同步网盘成功，共" + QString::number(validDisks.size()) + "个网盘");
        } else {
            qDebug() << "SyncDisksCommand: 同步网盘 - 响应中没有data字段或data不是数组";
            // 只有在对象仍然有效时才发送信号
            if (isValid()) {
                emit syncDisksCompleted(-4, "响应数据格式错误：缺少data字段");
            }
        }
    } else {
        qDebug() << "SyncDisksCommand: 同步网盘失败:" << errmsg;
        // 只有在对象仍然有效时才发送信号
        if (isValid()) {
            emit syncDisksCompleted(errcode, errmsg);
        }
    }
}

void SyncDisksCommand::syncRootFolders(const QJsonArray &disksData)
{
    if (!m_commandExecutor) {
        qDebug() << "SyncDisksCommand: CommandExecutor 未设置，无法同步根文件夹";
        return;
    }
    
    if (!disksData.isEmpty()) {
        qDebug() << "SyncDisksCommand: syncDisk执行完成，开始同步所有网盘的根文件夹，网盘数量:" << disksData.size();
        for (int i = 0; i < disksData.size(); ++i) {
            QJsonValue diskValue = disksData[i];
            if (diskValue.isObject()) {
                QJsonObject disk = diskValue.toObject();
                QString diskId = disk["id"].toString();
                QString diskName = disk["name"].toString();
                if (!diskId.isEmpty()) {
                    // 每次循环都检查 CommandExecutor 是否仍然有效
                    if (m_commandExecutor) {
                        qDebug() << "SyncDisksCommand: 同步网盘根文件夹，网盘ID:" << diskId << "网盘名称:" << diskName;
                        m_commandExecutor->executeSyncRootFolder(diskId);
                    } else {
                        qDebug() << "SyncDisksCommand: CommandExecutor 已被销毁，无法同步根文件夹，网盘ID:" << diskId;
                        break; // 如果 CommandExecutor 被销毁，停止循环
                    }
                }
            }
        }
    } else {
        qDebug() << "SyncDisksCommand: syncDisk执行完成，但没有网盘数据，跳过根文件夹同步";
    }
}

QString SyncDisksCommand::buildRequestUrl(const QString &baseUrl)
{
    return baseUrl + "/kms/api/kms/sync/disks";
}

